﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using GrayParrot.Web.Controls;
using GrayParrot.Core.Filters;
using Test.DAL;
using GrayParrot.Data.SqlTokenizer;


namespace FimetContoDeposito.BLL.ResultSets
{
    public class EmployeesResultSet : ResultSet<Employee>
	{
        public EmployeesResultSet(DTParameters param, IQueryable<Employee> result)
            : base(param, result)
        {
        }

        public override Expression<Func<Employee, bool>> ApplyGeneralFilter(string searchPattern)
        {
            var predicate = PredicateBuilder.False<Employee>();

            if (!string.IsNullOrWhiteSpace(searchPattern))
            {
                predicate = predicate.Or(im => im.FirstName != null && im.FirstName.ToString().Contains(searchPattern));
                predicate = predicate.Or(im => im.LastName != null && im.LastName.ToString().Contains(searchPattern));
                predicate = predicate.Or(im => im.Title != null && im.Title.ToString().Contains(searchPattern));
            }

            return predicate;
        }

        public override Expression<Func<Employee, bool>> ApplyGeneralColumnsFilter(List<string> columnSearch)
        {
            var predicate = PredicateBuilder.True<Employee>();

            string m_firstName = GetElement(1);
            string m_lastName = GetElement(2);
            string m_title = GetElement(3);

            if (!string.IsNullOrWhiteSpace(m_title))
            {
                predicate = predicate.And(im => im.Title.Contains(m_title));
            }

            if (!string.IsNullOrWhiteSpace(m_firstName))
            {
                predicate = predicate.And(im => im.FirstName.Contains(m_firstName));
            }

            if (!string.IsNullOrWhiteSpace(m_lastName))
            {
                predicate = predicate.And(im => im.LastName.Contains(m_lastName));
            }

            return predicate;
        }

        /// <summary>
        /// Applies the query builder filter.
        /// </summary>
        /// <param name="columnSearch">The column search.</param>
        /// 
        /// ParameterExpression argParam = Expression.Parameter(typeof(Service), "s");
        //  Expression nameProperty = Expression.Property(argParam, "Name");
        //  Expression namespaceProperty = Expression.Property(argParam, "Namespace");
        //  var val1 = Expression.Constant("Modules");
        //  var val2 = Expression.Constant("Namespace");
        //  Expression e1 = Expression.Equal(nameProperty, val1);
        //  Expression e2 = Expression.Equal(namespaceProperty, val2);
        //  var andExp = Expression.AndAlso(e1, e2);
        //  var lambda = Expression.Lambda<Func<Service, bool>>(andExp, argParam);
        //
        /// <returns></returns>
        public override Expression<Func<Employee, bool>> ApplyQueryBuilderFilter(string columnSearch)
        {
            string[] p1 = columnSearch.Split(new string[] { "AND" }, StringSplitOptions.RemoveEmptyEntries);

            var tokenizer = new Tokenizer(columnSearch);
            var tokens = tokenizer.GetTokens();

            foreach (var token in tokens)
            {
                if (token.Type == TokenType.String)
                {
                    token.Value = token.Value.TrimStart(new char[] { '\'' }).TrimEnd(new char[] { '\'' });
                }
            }

            Console.WriteLine(tokens);

            ParameterExpression argParam = Expression.Parameter(typeof(Employee), "s");

            //foreach (var token in tokens)
            //{
            //    Expression nameProperty = null;
            //    Expression e1 = null;
            //    nameProperty = Expression.Property(argParam, token.Value);
            //    e1 = Expression.Equal(nameProperty, Expression.Constant(tokens[2].Value));
            //    var lambda = Expression.Lambda<Func<Employee, bool>>(e1, argParam);
            //}

            Expression etotal = null;

            Expression nameProperty = null;
            Expression e1 = null;
            string operatore = string.Empty;

            foreach (var token in tokens)
            {


                switch (token.Type)
                {
                    case TokenType.None:
                        break;
                    case TokenType.Word:
                        // indica il nome della proprietà...
                        if((token.Value == "AND") || (token.Value == "OR"))
                        {
                            continue;
                        }
                        else
                        {
                        nameProperty = Expression.Property(argParam, token.Value);
                        }
                        break;
                    case TokenType.Keyword:
                        break;
                    case TokenType.Number:
                        break;
                    case TokenType.String:
                        if (operatore == "=")
                        {
                            e1 = Expression.Equal(nameProperty, Expression.Constant(token.Value));
                        }
                        break;
                    case TokenType.Symbol:
                        // indica il simbolo...
                        operatore = token.Value;
                        break;
                    case TokenType.Variable:
                        break;
                    default:
                        break;
                }

                if ((nameProperty != null) && (e1 != null) && (operatore != ""))
                {
                    if (etotal == null)
                    {
                        etotal = e1;
                    }
                    else
                    {
                        etotal = Expression.AndAlso(etotal, e1);
                    }

                    nameProperty = null;
                    e1 = null;
                    operatore = "";
                }
            }


            var lambda = Expression.Lambda<Func<Employee, bool>>(etotal, argParam);
            Console.WriteLine(lambda);




            return lambda;
        }


	}
}
